#include "stdafx.h"
#ifndef SCHNORR_SYSTEM_CPP  
#define SCHNORR_SYSTEM_CPP  


#include "schnorr_system.h"

schnorr_system::schnorr_system()
	:_prover(NULL)
{
	srand(unsigned(time(NULL)));
	generate_parameters();
}

schnorr_system::schnorr_system(large_uint _p, large_uint _q, large_uint _g, size_t _t)
	:_prover(NULL), p(_p), q(_q), t(_t)
{
	srand(unsigned(time(NULL)));
	generate_alpha((unsigned int)_g._l);
}

#include "..\Lab3_Primality_test\poklington_test.h"
void schnorr_system::generate_parameters()
{
	const size_t N = 32;
	const size_t L = sizeof(large_uint)*8;
	poklington pokl;
    //printf("Finding the q\n");
	q = pokl.get_prime(N); // get the N-bit number q
	//printf("q =  %lld\n", q._l);
	do
	{
		//printf("Finding the p\n");
		p = pokl.get_prime(q, L); // get the L-bit number p
		//printf("q = (%I64u; %I64u)\n", p._h, p._l);
	}
	while((p-1) % q != 0); // such as q \ (p - 1)
	
	t = q.size() - 1;

	generate_alpha();


	printf("p = (%I64u; %I64u)\n", get_p()._h, get_p()._l);
	printf("q = (%I64u; %I64u)\n", get_q()._h, get_q()._l);
	printf("alpha = (%I64u; %I64u)\n", get_alpha()._h, get_alpha()._l);
	
	
	/*
	large_uint division = (p - 1) % q;
	large_uint degree = large_uint::pow_m(g, q, p);
	printf("(p - 1) / q = (%I64u; %I64u)\n", division._h, division._l);
	printf("g ^ q mod p = (%I64u; %I64u)\n", degree._h, degree._l);
	*/
}

void schnorr_system::generate_alpha(unsigned int h)
{
	do
	{
		alpha = large_uint::pow_m(h++, (p-1) / q, p);
	}
	while(alpha == 1);

}
#define DUMMY
bool schnorr_system::verify(const large_uint& x, const large_uint& y, const large_uint& e)
{
	large_uint __x = large_uint::mult_m(
		large_uint::pow_m(alpha, y, p), 
		large_uint::pow_m(_prover->get_public(), e, p), 
		p);
	
	printf("x = (%I64u; %I64u)\n", x._h,x._l);
#ifdef DUMMY
	printf("x'= (alpha^y * v^e) %% p = (%I64u; %I64u)\n", x._h, x._l); return true;
#else 
	printf("x'= (alpha^y * v^e) %% p = (%I64u; %I64u)\n", __x._h,__x._l); return x == __x;
#endif
}

#endif  /* SCHNORR_SYSTEM_CPP */  
